class Evaluation:

    def __init__(self, usersget,goodsget):

        """
        对推荐算法recommend_algorithm计算各种评测指标

        :param :recommend_algorithm : ItemCF
        """
        self.usersget = usersget  # 算法
        self.goodsget = goodsget  # 算法

        self.precision = None  # 准确率
        self.recall = None  # 召回率
        self.gprecision = None  # 准确率
        self.grecall = None  # 召回率

    def evaluate(self):
        """
        评估指标计算
        """
        # 准确率和召回率

        self.precision, self.recall = self.__precision_recall()
        print('用户的准确率 = ' + str(self.precision * 100) + '% 召回率 = ' + str(self.recall * 100) + '%')
        self.gprecision, self.grecall = self.__goods_precision_recall()
        print('物品的准确率 = ' + str(self.gprecision * 100) + '% 召回率 = ' + str(self.grecall * 100) + '%')

    def __precision_recall(self):

        """
        计算准确率和召回率

        return: 准确率和召回率
        """

        # 得到测试集用户与其所有正反馈物品集合的映射
        test_user_items = dict()

        for user, item in self.usersget.items():
            if user not in test_user_items:
                test_user_items[user] = set()

            test_user_items[user].add(item)

        # 计算准确率和召回率

        hit = 0  # 分子
        all_ru = 0  # 分母
        all_tu = 0  # 分母

        for user, item in test_user_items.items():
            # 训练数据给用户的推荐列表
            ru = set(self.usersget)
            # 测试集数据给用户的推荐列表
            tu = item

            hit += len(ru & tu)
            all_ru += len(ru)
            all_tu += len(tu)

        return hit / all_ru, hit / all_tu


    def __goods_precision_recall(self):
        """
        计算准确率和召回率

        return: 准确率和召回率
        """

        # 得到测试集用户与其所有正反馈物品集合的映射
        test_user_items = dict()

        for user, item in self.goodsget.items():
            if user not in test_user_items:
                test_user_items[user] = set()

            test_user_items[user].add(item)

        # 计算准确率和召回率

        hit = 0  # 分子
        all_ru = 0  # 分母
        all_tu = 0  # 分母

        for user, item in test_user_items.items():
            # 训练数据给用户的推荐列表
            ru = set(self.goodsget)
            # 测试集数据给用户的推荐列表
            tu = item

            hit += len(ru & tu)
            all_ru += len(ru)
            all_tu += len(tu)

        return hit / all_ru, hit / all_tu
